﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VehicleConfigurator.Database;
using VehicleConfigurator.Model;
using VehicleConfigurator.NetUtils.Database;
using VehicleConfigurator.NetUtils;
using log4net;
using System.IO;
using VehicleConfigurator.NetUtils.Settings;
using System.Globalization;

namespace VehicleConfigurator
{
    public partial class FrmVehicleConfiguratorData : Form
    {
        static readonly ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); //Constructing log
        private object _1INSTANCE = null;
        public FrmVehicleConfiguratorData()
        {
            InitializeComponent();
        }

        List<string> deleteId = new List<string>();
        List<string> updateId = new List<string>();

        //User function
        private void GetMakeComboData()
        {
            clsDb db = new clsDb();

            string makeSql = "SELECT * FROM make ORDER BY Name ";
            DataTable dt = new DataTable();
            dt = db.GetDataTable(makeSql);
            cboMake.DataSource = dt;
            cboMake.DisplayMember = "Name";
            cboMake.ValueMember = "OID";
            if (dt != null)
                if (dt.Rows.Count > 0)
                    cboMake.SelectedIndex = 0;

        }
        private void GetOpionGroupComboData(string id)
        {
            //clsDb db = new clsDb();
            cboOptionGroup.ResetText();
            ////OptionGroup
            //string optionGroupSql = "SELECT * FROM optiongroup WHERE MakeOID in ({0})";
            //optionGroupSql = String.Format(optionGroupSql, id);
            DataTable dt2 = new DataTable();
            dt2 = DBAccess.GetOptionGroup(id);
            //dt2 = db.GetDataTable(optionGroupSql);
            cboOptionGroup.DataSource = dt2;
            cboOptionGroup.DisplayMember = FieldNames.NAME;
            cboOptionGroup.ValueMember = FieldNames.OID;
            if (dt2 != null)
                if (dt2.Rows.Count > 0)
                    cboOptionGroup.SelectedIndex = 0;
        }

        private void GetComboLanguageData()
        {
            try
            {
                DataTable dt = new DataTable();
                dt = DBAccess.GetLanguage();
                this.cboLanguage.DataSource = dt;
                this.cboLanguage.ValueMember = FieldNames.CODE;
                this.cboLanguage.DisplayMember = FieldNames.NAME;
                string index = "";
                DataRow[] result = dt.Select("IsDefault = 1");
                if (result.Length > 0)
                {
                    DataRow dr = result[0];
                    index = dr[FieldNames.CODE].ToString();
                }
                if (dt != null)
                    if (dt.Rows.Count > 0)
                        if (!index.Equals(""))
                            cboLanguage.SelectedValue = index;
                        else
                            cboLanguage.SelectedIndex = 0;

            }
            catch (Exception ex)
            {

                log.Error(ex.Message);
            }

        }

        private void ScrollToBottom()
        {
            var lastRow = this.dgvOptionTransaction.Rows.Count - 1;
            this.dgvOptionTransaction.FirstDisplayedScrollingRowIndex = lastRow;
        }

        private void TransactionTabGroupColumnData()
        {

            var comboBox = new DataGridViewComboBoxColumn();
            comboBox = this.dgvOptionTransaction.Columns["OptionGroupOID"] as DataGridViewComboBoxColumn;
            DataTable dt = new DataTable();
            dt = DBAccess.GetOptionGroup();
            comboBox.DataSource = dt;
            comboBox.ValueMember = FieldNames.OID;
            comboBox.DisplayMember = FieldNames.NAME;

        }



        void ReFormatGrid()
        {
            dgvOptionTransaction.AllowUserToAddRows = false;
            dgvOptionTransaction.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
        }
        void loadComponent()
        {
            if (_1INSTANCE == null)
            {
                _1INSTANCE = this;
            }
            else
            {
                return;
            }
            try
            {
                this.dgvOptionTransaction.DataSource = this.addDefaultColumn(null);
                this.GetMakeComboData();
                this.TransactionTabGroupColumnData();
                this.GetComboLanguageData();
            }
            catch (Exception ex)
            {
                
                //throw;
            }
        }


        void UpdateDataOption()
        {
            var db = new clsDb();
            db.updateData("`option`", this.dgvOptionTransaction);
        }
        DataTable addDefaultColumn(DataTable dt)
        {
            dt = new DataTable();
            DataColumn dc = new DataColumn("OID", typeof(int));
            dt.Columns.Add(dc);

            dc = new DataColumn("GroupOID", typeof(int));
            dt.Columns.Add(dc);

            dc = new DataColumn("OptionCode", typeof(String));
            dt.Columns.Add(dc);

            dc = new DataColumn("BaseName", typeof(String));
            dt.Columns.Add(dc);

            dc = new DataColumn("Explanation", typeof(String));
            dt.Columns.Add(dc);

            return dt;
        }

        int deleteItem(List<string> list)
        {
            int ret = -1;
            string id = "";
            id = Utils.getIdDelete(list);
            if (!id.Trim().Equals(""))
                ret = DBAccess.deleteTransaction(id);
            return ret;
        }
        void getListUpdate(string id)
        {
            if (updateId.IndexOf(id) == -1 & deleteId.IndexOf(id) == -1)
                updateId.Add(id);
        }
        void exportToCSVfile(string fileName)
        {
            try
            {
                var settings = AppConfig.GetExportSettings(ImportConfig.Constants.AM_IMPORT_COMMON);
                
                var separator = settings[ImportConfig.Format.CSV_SEPARATOR].GetDefault(",");
                

                DataTable dt = new DataTable();
                dt = (DataTable)this.dgvOptionTransaction.DataSource;
                DBAccess.ToCSV(this.dgvOptionTransaction, fileName, this.cboLanguage.SelectedValue.ToString(), separator);
                MessageBox.Show("Export successful. Path to file: " + fileName, "Information",
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                log.Error(ex.Message);
                //throw;
            }
        }

        void ImportFromCSV(string filepath)
        {
            var settings = AppConfig.GetImportSettings(ImportConfig.Constants.AM_IMPORT_COMMON);

            var separator = settings[ImportConfig.Format.CSV_SEPARATOR].GetDefault(",");

            List<string[]> listParse = DBAccess.parseCSV(filepath, separator);
            DataTable newTable = new DataTable();
            //add OID Column
           // newTable.Columns.Add();
            //newTable.Columns[0].ColumnName = FieldNames.OID;

            List<string> header = listParse[0].ToList();
            header.Insert(0, FieldNames.OID);

            for (int i = 0; i <= header.Count - 1; i++)
            {
                newTable.Columns.Add();
                if (i == 0)
                    newTable.Columns[0].ColumnName = FieldNames.OID;
                else if (i == 1)
                    newTable.Columns[1].ColumnName = FieldNames.OID_GROUP;
                else if (i == 2)
                    newTable.Columns[2].ColumnName = FieldNames.OPTION_CODE;
                else if (i == 3)
                    newTable.Columns[3].ColumnName = FieldNames.BASE_NAME;
                 else if (i == 4)
                    newTable.Columns[4].ColumnName = FieldNames.EXPLANATION;
                else
                    newTable.Columns[i].ColumnName = header[i];
            }

            listParse.RemoveAt(0);

            foreach (string[] row in listParse)
            {
                if (row.Length > 0)
                {
                    List<string> words = row.ToList();
                    words.Insert(0, "-1");
                    int groupOid = -1;
                    groupOid = DBAccess.getGroupOidFromName(words[1].ToString());
                    words[1] = groupOid.ToString();

                    newTable.Rows.Add(words.ToArray());
                }
            }
            //List<Option> insertList = new List<Option>();

            //foreach (DataRow r in newTable.Rows)
            //{
            //    Option o = this.getOption(r);
            //    insertList.Add(o);
                
            //}


            this.SaveGrid(newTable, true);
            MessageBox.Show("import complete");
           // this.btnSearch_Click(null, null);

        }


        private Option getOption(DataRow dr)
        {
            Option o = new Option();
            int oid = -1;
            bool tem = false;
            tem = int.TryParse(dr[FieldNames.OID].ToString(), out oid);
            if (tem)
                o.OID = oid;

            o.OptionCode = dr[FieldNames.OPTION_CODE].ToString();
            int val = -1;
            bool result = int.TryParse(dr[FieldNames.OID_GROUP].ToString(), out val);
            if (result)
                o.GroupOID = val;
            o.BaseName = dr[FieldNames.BASE_NAME].ToString();
            o.Explanation = dr[FieldNames.EXPLANATION].ToString();
            List<OptionName> opns = new List<OptionName>();

            if (dr.Table.Columns.Count >= 5)
            {
                for (int i = 5; i < dr.Table.Columns.Count; i++)
                {
                    OptionName opn = new OptionName();
                    opn.OID = -1;//unnecesary
                    opn.Name = dr[i].ToString();
                    if (o.OID != -1)
                        opn.OptionOID = o.OID;
                    int langoid = -1;
                    langoid = DBAccess.LangCodeToOID(dr.Table.Columns[i].ColumnName);
                    if (langoid != -1)
                    {
                        opn.LanguageOID = langoid;
                    }

                    opns.Add(opn);

                }
                o.opns = opns;
            }

            return o;

            // o.GroupOID = dr[FieldNames.
        }

        void SaveGrid(DataTable dt, bool isImport)
        {
            var countSuccess = 0;
            var countFailed = 0;
            var countExist = 0;
            var countDelete = 0;
            var countUpdate = 0;
            var added = dt.GetChanges(DataRowState.Added);
            if (added != null && added.Rows.Count > 0)
            {
                //var subModelTb = Utils.CopyColumns(added, "");

                foreach (var item in added.Rows)
                {
                    var dataRow = item as DataRow;
                    var o = getOption(dataRow);
                    var result = DBAccess.InsertOption(o);
                    if (result == 1)
                        countSuccess++;
                    else if (result == -1)
                        countFailed++;
                    else if (result == -2)
                    {
                        countExist++;
                        countFailed++;
                    }
                }


                if (isImport && (countFailed > 0 || countExist > 0))
                    MessageBox.Show(string.Format("Some of data cann't import. Please check log file for more details",
                        countSuccess, countFailed));
                if (isImport && countFailed == 0 && countExist == 0)
                    MessageBox.Show(string.Format("Import successful."));

            }
            var changes = dt.GetChanges(DataRowState.Modified);
            if (changes != null && changes.Rows.Count > 0)
            {

                foreach (var item in changes.Rows)
                {
                    var dataRow = item as DataRow;
                    var o = getOption(dataRow);
                    var result = DBAccess.UpdateOption(o);
                    if (result != -1)
                        countUpdate++;
                    else
                        countFailed++;
                }
                //MessageBox.Show(string.Format("Update successful: {0} item(s)", countUpdate));
            }

            if (deleteId.Count > 0)
            {
                //  int countDelete = -1;
                countDelete = this.deleteItem(this.deleteId);
                if (countDelete == -1)
                    countFailed++;

            }
            this.deleteId = new List<string>();
            dt.AcceptChanges();
            //if (!isImport)
            //    MessageBox.Show(string.Format("Create successful: {0} item(s).\nUpdate : {1} item(s).\nDelete: {2} item(s).\nFailed: {3} item(s).\nPlease check log file for more details",
            //        countSuccess, countUpdate, countDelete == -1 ? 0 : countDelete, countFailed));
           // this.btnSearch_Click(null, null);

        }



        //control event



        private void cboMake_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                //string id = cboMake.SelectedValue.ToString();
                
                var dtRow = this.cboMake.SelectedItem as DataRowView;
                var id = dtRow[FieldNames.OID].ToString();
                this.GetOpionGroupComboData(id);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void FrmVehicleConfiguratorData_Load(object sender, EventArgs e)
        {
            
            this.tabControl1.SelectedTab = this.translationTab;
            this.loadComponent();
           // this.btnSearch_Click(null, null);

        }

        private void tabControl1_Selected(object sender, TabControlEventArgs e)
        {

        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.tabControl1.SelectedTab == this.translationTab)
            {
                this.loadComponent();
                deleteId = new List<string>();
                this.TransactionTabGroupColumnData();
                this.btnSearch_Click(null, null);
            }
            else if (this.tabControl1.SelectedTab == this.optionPricelistTabPage)
            {
                this.optionPriceListControl1.LoadDataComponent();
            }
            else if (this.tabControl1.SelectedTab == this.modelPricelistTabPage)
            {
                this.modelPriceListControl1.LoadDataComponent();
            }
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            string makeOID = "";
            if (cboMake.DataSource != null & cboMake.SelectedValue != null)
                makeOID = cboMake.SelectedValue.ToString();
            string optionGroupOID = "";
            if (cboOptionGroup.DataSource != null & cboOptionGroup.SelectedValue != null)
                optionGroupOID = cboOptionGroup.SelectedValue.ToString();
            string q = "";
            
            if (string.IsNullOrEmpty(optionGroupOID))
            {
                MessageBox.Show("Select a Optiongroup");
            }
            else
            {
                q = txtFilterField.Text.Trim();

                string cmdText = "call getTransaction({0},'{1}')";
                cmdText = string.Format(cmdText, optionGroupOID, q);
                //MessageBox.Show(cmdText);
                clsDb db = new clsDb();
                DataTable dt = new DataTable();
                dt = db.excuteProc(cmdText);
                if (dt == null)
                    dt = this.addDefaultColumn(dt);


                this.dgvOptionTransaction.DataSource = dt;
            }

        }

        private void btnNewOptionCode_Click(object sender, EventArgs e)
        {
            try
            {
                DataTable dt = new DataTable();
                dt = (DataTable)this.dgvOptionTransaction.DataSource;
                if (dt != null)
                {

                    DataRow dr = dt.NewRow();
                    dr["OID"] = "-1";
                    dr["GroupOID"] = this.cboOptionGroup.SelectedValue == null ? DBNull.Value : this.cboOptionGroup.SelectedValue;
                    dr["OptionCode"] = "optioncode";
                    dr["BaseName"] = "BaseName";
                    dr["Explanation"] = "explanation";
                    dt.Rows.Add(dr);
                    this.ScrollToBottom();

                }
                else
                {
                    dt = new DataTable();
                    DataRow dr = dt.NewRow();
                    this.addDefaultColumn(dt);

                    this.TransactionTabGroupColumnData();

                    dr["OID"] = "-1";
                    if (this.cboOptionGroup.SelectedValue != null)
                        dr[1] = this.cboOptionGroup.SelectedValue;
                    else
                        dr[1] = DBNull.Value;
                    dr["OptionCode"] = "optioncode";
                    dr["BaseName"] = "BaseName";
                    dr["Explanation"] = "explanation";
                    dt.Rows.Add(dr);
                    this.dgvOptionTransaction.DataSource = dt;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        private void btnSave_Click(object sender, EventArgs e)
        {

         //   DialogResult result1 = MessageBox.Show("Are you sure to save the change?", "Confirm Message", MessageBoxButtons.YesNo);
          //  if (result1 == DialogResult.Yes)
            //{
                DataTable dt = new DataTable();
                dt = this.dgvOptionTransaction.DataSource as DataTable;

                try
                {
                    //this.newListOption(null);
                    //
                    //this.btnSearch_Click(sender, e);
                    //this.deleteId = new List<string>();
                    //this.updateId = new List<string>();
                    SaveGrid(dt, false);
                    this.deleteItem(this.deleteId);

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    log.Error(ex.Message);
                }
           // }

        }

        private void btnDeleteSelected_Click(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)this.dgvOptionTransaction.DataSource;
            foreach (DataGridViewRow item in this.dgvOptionTransaction.SelectedRows)
            {
                if (!item.Cells["OID"].Value.ToString().Equals("-1"))
                    deleteId.Add(item.Cells["OID"].Value.ToString());

                dgvOptionTransaction.Rows.RemoveAt(item.Index);

            }
            //if (deleteId.Count > 0)
            //    dt.AcceptChanges();

        }

        private void btnDuplicateSelected_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.dgvOptionTransaction.SelectedRows.Count > 0)
                {
                    DataTable dt = (DataTable)this.dgvOptionTransaction.DataSource;
                    int index = dgvOptionTransaction.SelectedRows[0].Index;
                    var desRow = dt.NewRow();
                    var sourceRow = dt.Rows[index];
                    desRow.ItemArray = sourceRow.ItemArray.Clone() as object[];
                    desRow[0] = "-1";
                    dt.Rows.Add(desRow);
                    // dt.AcceptChanges();
                    this.ScrollToBottom();

                }
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void dgvOptionTransaction_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            string id = "";
            id = this.dgvOptionTransaction.Rows[e.RowIndex].Cells["OID"].Value.ToString();
            if (!id.Trim().Equals(""))
                this.getListUpdate(id);
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            //Asks the filenam with a SaveFileDialog control.

            try
            {
                if (this.dgvOptionTransaction.Rows.Count > 0)
                {
                    SaveFileDialog saveFileDialogCSV = new SaveFileDialog();
                    saveFileDialogCSV.InitialDirectory = Application.ExecutablePath.ToString();

                    saveFileDialogCSV.Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*";
                    saveFileDialogCSV.FilterIndex = 1;
                    saveFileDialogCSV.RestoreDirectory = true;


                    if (saveFileDialogCSV.ShowDialog() == DialogResult.OK)
                    {
                        // Runs the export operation if the given filenam is valid.
                        exportToCSVfile(saveFileDialogCSV.FileName.ToString());
                    }
                }
                else
                {
                    MessageBox.Show("The grid is empty !");
                }
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message, "Eror", MessageBoxButtons.OK,
                MessageBoxIcon.Error);

            }
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog openFileDialogCSV = new OpenFileDialog();

                openFileDialogCSV.InitialDirectory = Application.ExecutablePath.ToString();
                openFileDialogCSV.Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*";
                openFileDialogCSV.FilterIndex = 1;
                openFileDialogCSV.RestoreDirectory = true;

                if (openFileDialogCSV.ShowDialog() == DialogResult.OK)
                {
                    this.ImportFromCSV(openFileDialogCSV.FileName.ToString());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Eror", MessageBoxButtons.OK,
                   MessageBoxIcon.Error);
            }

        }





    }
}
